using System;
using System.Collections.Generic;
using UnityEngine;

namespace GamePlay.Framework.Timer
{
    /// <summary>
    /// 计时器管理器，提供定时执行和延迟执行功能
    /// </summary>
    public class TimerManager : MonoBehaviour
    {
        #region 单例实现

        private static TimerManager _instance;

        public static TimerManager Instance
        {
            get
            {
                if (_instance == null)
                {
                    GameObject obj = new GameObject("TimerManager");
                    _instance = obj.AddComponent<TimerManager>();
                    DontDestroyOnLoad(obj);
                }
                return _instance;
            }
        }

        private void Awake()
        {
            if (_instance != null && _instance != this)
            {
                Destroy(gameObject);
                return;
            }

            _instance = this;
            DontDestroyOnLoad(gameObject);

            // 初始化计时器列表
            _timers = new List<TimerTask>();
            _timersByID = new Dictionary<string, TimerTask>();
            _removeList = new List<TimerTask>();
        }

        #endregion

        #region 字段和属性

        private List<TimerTask> _timers;
        private Dictionary<string, TimerTask> _timersByID;
        private List<TimerTask> _removeList;

        [SerializeField] private bool _debugMode = false;

        public bool DebugMode
        {
            get => _debugMode;
            set => _debugMode = value;
        }

        #endregion

        #region Unity生命周期

        private void Update()
        {
            UpdateTimers(Time.deltaTime);
        }

        #endregion

        #region 公共方法

        /// <summary>
        /// 创建一个延迟执行的计时器
        /// </summary>
        /// <param name="delay">延迟时间（秒）</param>
        /// <param name="callback">回调方法</param>
        /// <param name="id">计时器ID（可选）</param>
        /// <returns>计时器ID</returns>
        public string SetTimeout(float delay, Action callback, string id = null)
        {
            id = id ?? Guid.NewGuid().ToString();

            var timer = new TimerTask
            {
                ID = id,
                Interval = delay,
                RemainingTime = delay,
                Callback = callback,
                IsRepeating = false
            };

            AddTimer(timer);
            return id;
        }

        /// <summary>
        /// 创建一个重复执行的计时器
        /// </summary>
        /// <param name="interval">间隔时间（秒）</param>
        /// <param name="callback">回调方法</param>
        /// <param name="id">计时器ID（可选）</param>
        /// <returns>计时器ID</returns>
        public string SetInterval(float interval, Action callback, string id = null)
        {
            id = id ?? Guid.NewGuid().ToString();

            var timer = new TimerTask
            {
                ID = id,
                Interval = interval,
                RemainingTime = interval,
                Callback = callback,
                IsRepeating = true
            };

            AddTimer(timer);
            return id;
        }

        /// <summary>
        /// 清除计时器
        /// </summary>
        /// <param name="id">计时器ID</param>
        /// <returns>是否成功清除</returns>
        public bool ClearTimer(string id)
        {
            if (string.IsNullOrEmpty(id) || !_timersByID.TryGetValue(id, out TimerTask timer))
            {
                return false;
            }

            _removeList.Add(timer);
            _timersByID.Remove(id);

            if (_debugMode)
            {
                Debug.Log($"[TimerManager] 计时器已清除: {id}");
            }

            return true;
        }

        /// <summary>
        /// 暂停计时器
        /// </summary>
        /// <param name="id">计时器ID</param>
        /// <returns>是否成功暂停</returns>
        public bool PauseTimer(string id)
        {
            if (string.IsNullOrEmpty(id) || !_timersByID.TryGetValue(id, out TimerTask timer))
            {
                return false;
            }

            timer.IsPaused = true;

            if (_debugMode)
            {
                Debug.Log($"[TimerManager] 计时器已暂停: {id}");
            }

            return true;
        }

        /// <summary>
        /// 恢复计时器
        /// </summary>
        /// <param name="id">计时器ID</param>
        /// <returns>是否成功恢复</returns>
        public bool ResumeTimer(string id)
        {
            if (string.IsNullOrEmpty(id) || !_timersByID.TryGetValue(id, out TimerTask timer))
            {
                return false;
            }

            timer.IsPaused = false;

            if (_debugMode)
            {
                Debug.Log($"[TimerManager] 计时器已恢复: {id}");
            }

            return true;
        }

        /// <summary>
        /// 重置计时器时间
        /// </summary>
        /// <param name="id">计时器ID</param>
        /// <returns>是否成功重置</returns>
        public bool ResetTimer(string id)
        {
            if (string.IsNullOrEmpty(id) || !_timersByID.TryGetValue(id, out TimerTask timer))
            {
                return false;
            }

            timer.RemainingTime = timer.Interval;

            if (_debugMode)
            {
                Debug.Log($"[TimerManager] 计时器已重置: {id}");
            }

            return true;
        }

        /// <summary>
        /// 清除所有计时器
        /// </summary>
        public void ClearAllTimers()
        {
            _timers.Clear();
            _timersByID.Clear();
            _removeList.Clear();

            if (_debugMode)
            {
                Debug.Log("[TimerManager] 所有计时器已清除");
            }
        }

        #endregion

        #region 私有方法

        private void AddTimer(TimerTask timer)
        {
            _timers.Add(timer);
            _timersByID[timer.ID] = timer;

            if (_debugMode)
            {
                Debug.Log($"[TimerManager] 新增计时器: {timer.ID}, 间隔: {timer.Interval}秒, 重复: {timer.IsRepeating}");
            }
        }

        private void UpdateTimers(float deltaTime)
        {
            // 清空待移除列表
            _removeList.Clear();

            // 更新所有计时器
            foreach (var timer in _timers)
            {
                if (timer.IsPaused)
                    continue;

                timer.RemainingTime -= deltaTime;

                if (timer.RemainingTime <= 0)
                {
                    try
                    {
                        timer.Callback?.Invoke();
                    }
                    catch (Exception ex)
                    {
                        Debug.LogError($"[TimerManager] 执行计时器回调时出错: {ex.Message}");
                    }

                    if (timer.IsRepeating)
                    {
                        // 重置重复计时器
                        timer.RemainingTime = timer.Interval;
                    }
                    else
                    {
                        // 标记一次性计时器待移除
                        _removeList.Add(timer);
                        _timersByID.Remove(timer.ID);
                    }
                }
            }

            // 移除完成的一次性计时器
            foreach (var timer in _removeList)
            {
                _timers.Remove(timer);
            }
        }

        #endregion

        #region 内部类

        private class TimerTask
        {
            public string ID { get; set; }
            public float Interval { get; set; }
            public float RemainingTime { get; set; }
            public Action Callback { get; set; }
            public bool IsRepeating { get; set; }
            public bool IsPaused { get; set; }
        }

        #endregion
    }
}